import viewSubclassKt from '../../examples/files/native_modules/viewSubclass.kt'
import viewSubclassSwift from '../../examples/files/native_modules/viewSubclass.swift'
import viewManagerKt from '../../examples/files/native_modules/viewManager.kt'
import viewManagerSwift from '../../examples/files/native_modules/viewManager.swift'
import MyPackageKt from '../../examples/files/native_modules/MyPackage.kt'
import MainApplicationJava from '../../examples/files/native_modules/MainApplication.java'
import MyView from '../../examples/files/native_modules/MyView.m'
import requireNativeComponent from '../../examples/files/native_modules/requireNativeComponent.js'
import PropsSwift from '../../examples/files/native_modules/Props.swift'
import PropsKt from '../../examples/files/native_modules/Props.kt'
import PropsM from '../../examples/files/native_modules/Props.m'
import PropsJs from '../../examples/files/native_modules/Props.js'

Native modules let us access native APIs through JavaScript. All of the built-in components, like `View` and `Image`, are native modules. There are also non-component native modules, like the `Animated` module.

## Bridging APIs

When writing a native module to expose native APIs, we call this **bridging** an API. The process for bridging components and non-component APIs is somewhat different, but the main idea is the same: we need to register a native Swift/Kotlin function to handle each JavaScript function call. React Native includes classes/methods/macros for registering these functions from native code.

In this guide we'll briefly cover the steps involved in bridging a component.

> Bridging an API is fairly formulaic, but may be difficult if you don't have native development experience.

## Bridging a component

How to expose a native UI component to JavaScript:

1. Create a native UIView or Android View subclass
2. Create a React ViewManager subclass that manages a pool of the view subclass
3. Register the ViewManager subclass with React Native
4. `requireNativeComponent` from JS

> These steps are essentially the same for iOS and Android.

Tip: be careful with names! The names of the annotations _do_ matter. Replace "My" in the examples with the component name you want.

---

### 1. Create a native view subclass

This can be any view - there's nothing specific to React Native yet.

<Example
  height={200}
  panes={['editor']}
  initialTab="MyView.kt"
  files={{
    'MyView.kt': viewSubclassKt,
    'MyView.swift': viewSubclassSwift,
  }}
/>

---

### 2. Create a ViewManager subclass

A ViewManager manages a pool of our View subclass from the previous step. Native views are reused as much as possible for better performance.

<Example
  height={400}
  panes={['editor']}
  files={{
    'MyViewManager.kt': viewManagerKt,
    'MyViewManager.swift': viewManagerSwift,
  }}
/>

---

### 3. Register the ViewManager subclass

We need to let React Native know about our ViewManager by registering it.

<Example
  height={300}
  panes={['editor']}
  files={{
    'MyPackage.kt': MyPackageKt,
    'MainApplication.java': MainApplicationJava,
    'MyView.m': MyView,
  }}
/>

---

### 4. Load the native module from JS

Once we've registered a ViewManager on the native side, we can instantiate the view as a React component.

<Example height={300} panes={['editor']} code={requireNativeComponent} />

---

### 5. Props

Next, we need to pass props from JS to native:

<Example
  height={500}
  panes={['editor']}
  files={{
    'MyView.js': PropsJs,
    'MyViewManager.kt': PropsKt,
    'MyView.swift': PropsSwift,
    'MyView.m': PropsM,
  }}
/>

---

## Also...

Since React Native projects are in Obj-C & Java:

- Let Android Studio enable Kotlin
- Let Xcode add a bridging header
